package com.cnswhy.cloud.server.app.controller.customer;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cnswhy.cloud.common.core.exception.BizException;
import com.cnswhy.cloud.common.core.mybatis.conditions.Wraps;
import com.cnswhy.cloud.common.core.utils.CnswhyUtil;
import com.cnswhy.cloud.common.logging.uitls.MDCUtil;
import com.cnswhy.cloud.common.rabbitmq.service.MessageService;
import com.cnswhy.cloud.common.redis.service.IdGeneratorService;
import com.cnswhy.cloud.common.redis.service.RedisService;
import com.cnswhy.cloud.server.app.config.JsApiPay;
import com.cnswhy.cloud.server.app.config.WxPayApi;
import com.cnswhy.cloud.server.app.config.WxPayData;
import com.cnswhy.cloud.server.app.controller.BaseController;
import com.cnswhy.cloud.server.app.utils.RSAUtils;
import com.cnswhy.cloud.server.common.entity.constant.AmqpExchange;
import com.cnswhy.cloud.server.common.entity.enumeration.OrderPfxEnum;
import com.cnswhy.cloud.server.common.entity.enumeration.PayType;
import com.cnswhy.cloud.server.common.entity.mq.OrderQueryMQ;
import com.cnswhy.cloud.server.core.config.AlipayConfig;
import com.cnswhy.cloud.server.core.constant.RedisConstant;
import com.cnswhy.cloud.server.core.dto.MakeOrderBo;
import com.cnswhy.cloud.server.core.entity.*;
import com.cnswhy.cloud.server.core.oem.OemService;
import com.cnswhy.cloud.server.core.query.QueryGenerator;
import com.cnswhy.cloud.server.core.service.CustomerUpgradeMenuService;
import com.cnswhy.cloud.server.core.service.CustomerUpgradeTransOrderService;
import com.cnswhy.cloud.server.core.service.SysConfigService;
import com.cnswhy.cloud.server.core.service.customer.CustomerAlipayService;
import com.cnswhy.cloud.server.core.utils.PasswordCoder;
import com.cnswhy.cloud.server.core.vo.RespVo;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.service.WxPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Controller
@Api(tags = "customerUpgrade")
@RequestMapping("/customerUpgrade")
@Slf4j
public class CustomerUpgradeController extends BaseController {
    @Autowired
    CustomerUpgradeMenuService customerUpgradeMenuService;
    @Autowired
    CustomerUpgradeTransOrderService customerUpgradeTransOrderService;
    @Autowired
    IdGeneratorService idGeneratorService;
    @Autowired
    WxPayService wxPayService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private OemService oemService;
    @Autowired
    MessageService messageService;
    @Autowired
    SysConfigService sysConfigService;

    @ApiOperation(value = "查询套餐列表", httpMethod = "POST")
    @RequestMapping("/ajaxPageData")
    @ResponseBody
    public RespVo ajaxPageData(@RequestParam(name = "currentPage", defaultValue = "1") Integer currentPage,
                               @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {

        RespVo vo = new RespVo();
        try {
            Page<CustomerUpgradeMenu> page = new Page<>(currentPage, pageSize);
            IPage<CustomerUpgradeMenu> pageList = customerUpgradeMenuService.page(page, Wraps.<CustomerUpgradeMenu>lbQ().eq(CustomerUpgradeMenu::getStatus,1));
            vo.setCode(RespVo.CODE_SUCCESS);
            vo.setResult(pageList);
        } catch (Exception e) {
            vo.setCode(RespVo.CODE_ERROR);
            vo.setMessage("查询套餐列表失败");
            log.error("查询套餐列表失败", e);
        }
        return vo;
    }
    @ApiOperation(value = "query", httpMethod = "POST")
    @RequestMapping("/query")
    @ResponseBody
    public RespVo query(Long id) {
        RespVo vo = new RespVo();
        try {
            vo.setResult(customerUpgradeMenuService.getById(id));
            vo.setCode(RespVo.CODE_SUCCESS);
            vo.setMessage("查询套成功");
        } catch (Exception e) {
            vo.setCode(RespVo.CODE_ERROR);
            vo.setMessage("查询套失败");
            log.error("查询套失败", e);
        }
        return vo;
    }
    /**
     * 描述：下单
     * 作者：张润泽
     * 时间：2019年8月29日 上午10:14:53
     *
     * @param
     * @param request
     * @return
     */
    @ApiOperation(value = "下单")
    @ApiParam(name = "makeOrderJson", value = "下单json字符串")
    @RequestMapping("/makeOrderPay")
    @ResponseBody
    public RespVo makeOrder(@RequestParam(name = "menuId") String menuId, @RequestParam(name = "payType") String payType, HttpServletRequest request) {
        RespVo respVo = new RespVo();
        try {
            Customer loginCustomer = getLoginCustomer( request);
            CustomerUpgradeMenu customerUpgradeMenu = customerUpgradeMenuService.getById(Long.valueOf(menuId));
            if(customerUpgradeMenu.getStatus() != 1){
                throw new BizException("套餐已经失效");
            }
            Integer type = Integer.valueOf(payType);
            if(type != 2 && type != 3){
                throw new BizException("payType[2 alipay 3 wx]");
            }
            CustomerUpgradeTransOrder customerUpgradeTransOrder = new CustomerUpgradeTransOrder();
            customerUpgradeTransOrder.setMenuId(customerUpgradeMenu.getId());
            customerUpgradeTransOrder.setStatus(1);
            customerUpgradeTransOrder.setCustomerId(loginCustomer.getId());
            customerUpgradeTransOrder.setTransAmt(customerUpgradeMenu.getMenuAmt());
            customerUpgradeTransOrder.setPayType(type);
            customerUpgradeTransOrder.setOrderId("UG" + idGeneratorService.genCommonIdString());
            customerUpgradeTransOrderService.save(customerUpgradeTransOrder);
            String body = "UPGRADE";
            if(type == 3){

                SysConfig sysConfig = sysConfigService.getOne(Wraps.<SysConfig>lbQ().eq(SysConfig::getConfigKey, "wxPaySys").eq(SysConfig::getDisplayStatus, "1"));
                String notifyUrl = (String) redisService.hget(RedisConstant.SYS_CONFIG_1, RedisConstant.WX_NOTIFY_URL);
                JsApiPay jsApiPay = new JsApiPay(null, customerUpgradeTransOrder.getTransAmt().intValue(), sysConfig.getValidateRules(), sysConfig.getConfigValue(),
                        notifyUrl, sysConfig.getConfigRules(), "", "APP");
                WxPayData wxData = jsApiPay.GetUnifiedOrderResult(customerUpgradeMenu.getMenuName(), "交易编号：" + customerUpgradeTransOrder.getOrderId(), customerUpgradeTransOrder.getOrderId(), body,CnswhyUtil.getHttpServletRequestIpAddress());
                if (StringUtils.equals(wxData.GetValue("return_code").toString(), "SUCCESS")
                        && StringUtils.equals(wxData.GetValue("result_code").toString(), "SUCCESS")) {
                    Date beijingDate = Calendar.getInstance(Locale.CHINA).getTime();
                    String timeStamp = String.valueOf(beijingDate.getTime() / 1000);
                    SortedMap<String, Object> map2 = new TreeMap<String, Object>();
                    map2.put("appid", sysConfig.getConfigValue());
                    map2.put("timestamp", timeStamp);
                    map2.put("noncestr", wxData.GetValue("nonce_str"));
                    map2.put("prepayid", wxData.GetValue("prepay_id"));
                    map2.put("package", "Sign=WXPay");
                    map2.put("partnerid", wxData.GetValue("mch_id"));
                    String paySign = WxPayApi.createSign(map2, sysConfig.getConfigRules());
                    map2.put("sign", paySign);
                    respVo.setCode(RespVo.CODE_SUCCESS);
                    respVo.setResult(map2);
                    OrderQueryMQ orderQueryMQ = OrderQueryMQ.builder().orderId(customerUpgradeTransOrder.getOrderId()).queryTimes(0L).build();
                    orderQueryMQ.setPayType(PayType.wx);
                    orderQueryMQ.setBody(body);
                    orderQueryMQ.setTraceId(MDCUtil.getTraceId());
                    messageService.sendAndQueryTimes(AmqpExchange.ORDER_QUERY_MESSAGE, orderQueryMQ, orderQueryMQ.getQueryTimes());
                    return respVo;
                } else {
                    respVo.setCode(RespVo.CODE_ERROR);
                    respVo.setMessage("发起微信支付失败");
                    return respVo;
                }
            }else if(type == 2){
                //取库中支付宝参数
                SysConfig sysConfig = sysConfigService.getOne(Wraps.<SysConfig>lbQ().eq(SysConfig::getConfigKey, "aliPaySys").eq(SysConfig::getDisplayStatus, "1"));

                AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, sysConfig.getConfigValue(),
                        sysConfig.getValidateRules(), AlipayConfig.FORMAT, AlipayConfig.CHARSET,
                        sysConfig.getConfigRules(), AlipayConfig.SIGNTYPE);
                // AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();

                AlipayTradeAppPayRequest alipay_request = new AlipayTradeAppPayRequest();
                // 封装请求支付信息
                AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
                model.setOutTradeNo(customerUpgradeTransOrder.getOrderId());
                model.setSubject("支付订单" + customerUpgradeTransOrder.getOrderId());
                model.setTotalAmount(String.format("%.2f",customerUpgradeTransOrder.getTransAmt().doubleValue() / 100));
                model.setBody(body);
                model.setTimeoutExpress("2m");
                model.setProductCode("QUICK_MSECURITY_PAY");
                alipay_request.setBizModel(model);


                // 设置异步通知地址
                alipay_request.setNotifyUrl(
                        (String) redisService.hget(RedisConstant.SYS_CONFIG_1, RedisConstant.ALIPAY_NOTIFY_URL));
                // 设置同步地址
                alipay_request.setReturnUrl("http://renrenpin.shop/#/pages/my/order/order?idx=0");
                AlipayTradeAppPayResponse alipayTradeAppPayResponse = client.sdkExecute(alipay_request);
                // 就是orderString 可以直接给APP请求，无需再做处理。
                String orderString = alipayTradeAppPayResponse.getBody();
                respVo.setResult(orderString);
                respVo.setCode(0);
                OrderQueryMQ orderQueryMQ = OrderQueryMQ.builder().orderId(customerUpgradeTransOrder.getOrderId()).queryTimes(0L).build();
                orderQueryMQ.setPayType(PayType.alipay);
                orderQueryMQ.setBody(body);
                orderQueryMQ.setTraceId(MDCUtil.getTraceId());
                messageService.sendAndQueryTimes(AmqpExchange.ORDER_QUERY_MESSAGE, orderQueryMQ, orderQueryMQ.getQueryTimes());
            }
        } catch (BizException e) {
            return RespVo.fail(e.getMessage());
        } catch (Exception e) {
            respVo.setCode(RespVo.CODE_ERROR);
            respVo.setMessage("下单失败");
            log.error("下单异常：", e);
        }
        return respVo;
    }


}
